C 本身相对简单,各种操作系统都能设立自己的统一 C ABI 。而 C++ 的 ABI 要求比 C 复杂很多,以至于各大编译器提供者有长久的分歧,同系列编译器的不同版本间不时也出现分歧。
新写的操作系统,要在上面搭建一个开发环境套件,首先考虑移植上去的语言几乎一定是C。
提供的用户态接口基本也是 C的。无它,容易,而且你C++不是兼容C嘛,我干嘛要提供C++接口来抛弃C程序员呢(类似很多windows应用程序坚持只提供x86而不提供x64版本一样)。操作系统动态库的某些API对C支持较为方便,让C几乎成了动态库的标准接口语言。其他语言也选择动态库来和其他语言交互,因为3,不得不也对C和他的ABI产生一些依赖。
综上,从操作系统到其他非C/C++语言,整个软件生态体系都对C语言有依赖,C++何以言取代之?Objective c++还兼容C++呢,除了从事特殊底层开发的,有几个人用过?
C++ 编译器实现太复杂,很多嵌入式平台都只支持 C(如很多 DSP 芯片)。就算支持 C++,往往也不是所有特性都支持,最典型的就是异常和 RTTI(这个主要是为了减少二进制文件体积以及运行时占用的内存的大小,因为这些功能在 DSP 上几乎用不到)。
另外就是,C 作为各大操作系统的原生接口,在 ABI 兼容性方面有着不可替代的优势。
一味地强调C++不完全兼容C就不合适了。C++对C的兼容是全方位的,不兼容的部分只是一些边角细节。还要强调这些细节的存在,就像你在嫌一件衣服卖1000太贵的时候,旁边的人说道:可它明明只卖998!
题主你产生疑问的一部分原因,在于你接触IT业比较晚,没有了解过这两种语言的发展。早期没有C++的时候,C语言占据了编程语言的超过半壁江山。到C++出现的时候,大家很快开始转移到C++等功能更强的语言,C语言的份额迅速萎缩,到了现在,已经只有系统内核,驱动,嵌入式等少数几个领域还是C语言的天下。所以很大程度上,C语言确实是被C++取代了。
如果仅以现代的眼光看,C语言的代码,基本上都能用C++编译通过,语法,语义,性能都基本一致,但独立的C语言一直顽强地生存着,这似乎就令人费解了。
这背后的原因,在于之前提到的几个领域仍然需要C语言。在这些里,C语言仍然有着不可替代的优势。C的特点,是简单,直白,功能少,性能高,程序员控制一切。在这里,C的弱点被掩盖,而优点能最大程度地发挥。
毕竟C最初就是为了这些场合而开发出来的。
C简单?好事。简单意味着编译器容易实现,质量高,bug少。简单还意味着大家的实现不容易产生分歧,为ABI的统一提供了便利。C功能少,总是需要自己造轮子?没关系。做内核,做嵌入式,就算有现成的轮子,也经常不再适用,自造轮子是家常便饭。而且功能少的情况下,资源消耗也会极大地减少。整个系统可以运行在存储空间只有4M,内存只有64K的环境下。换其他语言,运行库就要把存储空间撑爆了。
C开发繁琐,效率低?这些领域的需求一般都不会变来变去,逻辑通常也不会特别复杂。
C手动管理资源,容易出错?内核等场合下,我们本来就是要自己实现资源的管理。而且我们正是要手动控制一切,才能最大程度地精打细算。这些场合只有C最适用。包括C++在内的其他语言都尝试过,但都无法撼动C的地位。这就是独立的C语言仍然存在的理由。
主要问题是语言复杂度太高,使得人书写难度变大,变相阻碍了语言发展。
表面问题是runtime,C功能更精简,底层提供一个runtime以及配套的编译器更方便。LLVM的出现理论上应该大大降低了这一门槛,但现实是C++依旧没多大起色,所以我觉得这个只是表面的问题。
虚假问题是ABI。诚然C++没有统一的ABI,但这不妨碍一个组件用C++编写并提供纯C的接口(虽然这也会失去C++的许多功能优势,但换个角度,哪个用纯C接口的库能带上自己语言的花式特性的啊?)。
事实上,我觉得除了底层受限的情况(如内核、嵌入式开发、资源稀缺,或者是不想依赖C++runtime),任何新项目都不应该用C去写。
C++特性是多是复杂,但本身并不要求你使用全部特性。
用constexpr代替部分宏不好吗?用模板代替部分宏不好吗?
还有各种有利于开发维护的特性。
那些说C编译出的二进制结果确定的还是醒醒吧,难道你编译C不开优化的吗?想要精确控制就上汇编,C的语言规范里有说保证编译结果与代码一一对应吗……
归根到底,C++太复杂了,复杂到用户还没学就被吓跑了,复杂到C用户没法低成本享受高方便。
完全取代是一定不可能的,但没能成功地大量侵占C的地盘,这还是得赖C++自己。
C语言的规则比较简单,编译结果比较确定,而C++的许多语法编译出的结果随着编译器不同而有很大变化,这就容易产生不可控因素,对于一些稳定性要求很高、对内存排布敏感的情况就可能出现复杂的难以调试的bug。那可能还不如一开始就限定只用C语法。另外,C可以不链接任何库,但C++不行(new和delete的默认实现无论如何都得有),这就限制了在内核中的应用。没必要贬低C++,各有各的应用场景而已。
要明确C语言是C++的子集这种说法是错误的,也只是说“几乎可以看作”。可以看出,其实C++和C的理念和语言特性有很大的不同。然后,为什么C语言没有被C++取代,这个问法也是不严谨的,可以说,为什么C没有完全被C++取代。原因主要可以归结于两者都是独立的语言,且面向的场景已经有所不同。
就目前而言底层硬件依然是C的天下,虽然C++一样可以进行这方面的工作,但是从历史遗留原因和C语言天然的优势,C++极难在这方面完全取而代之。
而其他方面,在C++出现后大部分使用C的场景被C++所取代,甚至连windows这类操作系统底层部分模块也使用C++来实现,我们可以把它看作是时代进步、科技发展的必然结果。同样的,我们可以看到现如今,很多属于C++的阵地被Java、C#、python、go这类热门语言攻克,但同样不能说这些语言就能代替C++。
我们可以把C++想像成语言中的瑞士军刀,而诸如C、Java这类语言更类似于专门的螺丝刀、平口刀。瑞士军刀固然重要,但也许在某些工作中使用专门的工具会更加合适。同样,我们在某些开发领域选择语言时往往希望其可以专注一件事,而不是面面俱到、无限可能。
C语言和汇编语言构筑了今天计算机世界的地基。足够底层,离不开这两者,我们天天跟C语言打交道,只是没有意识到而已。C语言并非简单的是C++的子集,这只能从C++的角度来看,否则完全是另一个场景,C++之父确实要设计并取代C语言,但没有成功,他自己也公开承认。不仅过去,现在,包括将来,C语言是不可替代的。你可以在不少领域找到理由说明C语言是如何弱势,但也只能说说而已,在你看不见的更多地方,或者能力不及无法触及的位置,C语言就矗立在那里,像独孤求败。并不夸大C语言,也不是C语言的拥趸,我只是一个确实知道C语言很强大也很伟大的人,是的,这门编程语言值得用伟大这个词。
本页共31段,2892个字符,7913 Byte(字节)